package com.zxp.biz.payment.start;

import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
import com.wechat.pay.contrib.apache.httpclient.auth.Verifier;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator;
import com.wechat.pay.contrib.apache.httpclient.cert.CertificatesManager;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import com.zxp.biz.payment.WxMchContent;
import com.zxp.biz.payment.entity.WxMch;
import com.zxp.biz.payment.service.WxMchService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.impl.client.CloseableHttpClient;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.PrivateKey;
import java.util.List;

/**
 * @author zxp
 * @date 2021-12-27 15:53
 */

@Component
@Order(2)
@Slf4j
@AllArgsConstructor
public class WxMchInit implements CommandLineRunner {

    private final WxMchService wxMchService;

    /**
     * 获取商户的私钥文件
     * @param filename
     * @return
     */
    private PrivateKey getPrivateKey(String filename){

        // getClassLoader加载不需要/，class.getResource()是以resources为根目录的绝对路径，文件名（参数）前面需要加/
        InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(filename);

        // new FileInputStream( filename )
        try {
            if (is == null) { //不是放在resource目录下，
                is = new FileInputStream(filename);
            }
            return PemUtil.loadPrivateKey(is);
        } catch (Exception e) {
            throw new RuntimeException("私钥文件不存在", e);
        }
    }

    @Override
    public void run(String... args) throws Exception {
        log.debug("启动："+args);

        List<WxMch> list = wxMchService.list();

        log.debug("获取所有的商户号："+list);

        if (!ObjectUtils.isEmpty(list)){
            for (WxMch wxMch: list) {

                String mchId = wxMch.getMchId();
                String mchSerialNo = wxMch.getMchSerialNo();


                //获取商户私钥
                PrivateKey privateKey = getPrivateKey( wxMch.getPrivateKeyPath());

                //私钥签名对象
                PrivateKeySigner privateKeySigner = new PrivateKeySigner(mchSerialNo, privateKey);

                //身份认证对象
                WechatPay2Credentials wechatPay2Credentials = new WechatPay2Credentials(mchId, privateKeySigner);

                CertificatesManager certificatesManager = CertificatesManager.getInstance();
                certificatesManager.putMerchant(mchId,wechatPay2Credentials, wxMch.getApiV3Key().getBytes(StandardCharsets.UTF_8));
                Verifier verifier = certificatesManager.getVerifier(mchId);

                //用于构造HttpClient
                WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
                        //设置商户信息
                        .withMerchant(mchId, mchSerialNo, privateKey)
                        .withValidator(new WechatPay2Validator(verifier));

                // 通过WechatPayHttpClientBuilder构造的HttpClient，会自动的处理签名和验签，并进行证书自动更新
                WxMchContent.httpClients.put(mchId, builder.build());

                log.info("获取签名验证器");

                // 使用定时更新的签名验证器，不需要传入证书, 以前的用法
                //ScheduledUpdateCertificatesVerifier verifier = new ScheduledUpdateCertificatesVerifier(
                //        wechatPay2Credentials,
                //        wxMch.getApiV3Key().getBytes(StandardCharsets.UTF_8));

                 //WxMchContent.verifiers.put(wxMch.getMchId(), verifier);


                //用于构造HttpClient
                WechatPayHttpClientBuilder builder2 = WechatPayHttpClientBuilder.create()
                        //设置商户信息
                        .withMerchant(mchId, mchSerialNo, privateKey)
                        //无需进行签名验证、通过withValidator((response) -> true)实现
                        .withValidator((response) -> true);

                // 通过WechatPayHttpClientBuilder构造的HttpClient，会自动的处理签名和验签，并进行证书自动更新
                log.info("== getWxPayNoSignClient END ==");

                //WxMchContent.wxPayNoSignClients.put(wxMch.getMchId(), builder2.build());
            }
        }
    }
}
